using AutoMapper;
using MediatR;
using RBAC.Domain.Dto.Output;
using RBAC.Domain.MaterialManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.ERP.MaterialFile;
using System.Text;

namespace RBAC.Read.Api.Application.Handler.ERP.MaterialFile
{
    /// <summary>
    /// 获取物料分页列表处理程序
    /// 支持物料编码、物料名称文本查询和树状图节点分类筛选
    /// </summary>
    public class GetMaterialPageHandler : IRequestHandler<GetMaterialPageCommand, APIResult<APIPaging<GetMaterialListDto>>>
    {
        private readonly IBaseRepository<Mater> materRepository;
        private readonly IBaseRepository<MaterType> materTypeRepository;
        private readonly IMapper mapper;
        private readonly ILogger<GetMaterialPageHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="materRepository">物料仓储</param>
        /// <param name="materTypeRepository">物料分类仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetMaterialPageHandler(
            IBaseRepository<Mater> materRepository,
            IBaseRepository<MaterType> materTypeRepository,
            IMapper mapper,
            ILogger<GetMaterialPageHandler> logger)
        {
            this.materRepository = materRepository;
            this.materTypeRepository = materTypeRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 处理获取物料分页列表请求
        /// </summary>
        /// <param name="request">查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页物料列表数据</returns>
        public async Task<APIResult<APIPaging<GetMaterialListDto>>> Handle(GetMaterialPageCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<APIPaging<GetMaterialListDto>>();

            try
            {
                logger.LogInformation("开始获取物料分页列表，页码: {PageIndex}, 页大小: {PageSize}, 物料编码: {MaterialCode}, 物料名称: {MaterialName}, 分类ID: {TypeId}",
                    request.PageIndex, request.PageSize, request.MaterialCode, request.MaterialName, request.TypeId);

                // 参数验证
                if (request.PageIndex <= 0) request.PageIndex = 1;
                if (request.PageSize <= 0) request.PageSize = 20;
                if (request.PageSize > 100) request.PageSize = 100; // 限制最大页大小

                // 构建查询条件
                var whereClause = new StringBuilder("m.IsDeleted = 0"); // 使用0代替false，避免MySQL类型转换问题
                var parameters = new Dictionary<string, object>();

                // 物料编码模糊查询
                if (!string.IsNullOrWhiteSpace(request.MaterialCode))
                {
                    whereClause.Append(" AND m.MaterCode LIKE @MaterialCode");
                    parameters.Add("MaterialCode", $"%{request.MaterialCode.Trim()}%");
                }

                // 物料名称模糊查询
                if (!string.IsNullOrWhiteSpace(request.MaterialName))
                {
                    whereClause.Append(" AND m.MaterName LIKE @MaterialName");
                    parameters.Add("MaterialName", $"%{request.MaterialName.Trim()}%");
                }

                // 树状图节点分类筛选
                if (request.TypeId.HasValue && request.TypeId.Value > 0)
                {
                    // 获取该分类及其所有子分类的ID列表
                    var typeIds = await GetAllChildTypeIds(request.TypeId.Value);
                    if (typeIds.Count > 1) // 如果有子分类
                    {
                        // 使用字符串拼接构建IN子句，避免Dapper参数传递问题
                        var typeIdsParam = string.Join(",", typeIds);
                        whereClause.Append($" AND m.MaterTypeId IN ({typeIdsParam})");
                    }
                    else // 只有当前分类
                    {
                        whereClause.Append(" AND m.MaterTypeId = @TypeId");
                        parameters.Add("TypeId", request.TypeId.Value);
                    }
                }

                // 查询总记录数
                var countSql = $"SELECT COUNT(*) FROM Mater m WHERE {whereClause}";
                var totalCount = materRepository.QueryFirstOrDefault<int>(countSql, parameters);

                // 查询分页数据
                var offset = (request.PageIndex - 1) * request.PageSize;
                var dataSql = $@"
                    SELECT 
                        m.Id,
                        m.MaterCode AS MaterialCode,
                        m.MaterName AS MaterialName,
                        m.ModelSpec AS Specification,
                        m.SpecDesc AS SpecificationDesc,
                        m.Unit,
                        m.SupplyMode AS SupplyMethod,
                        m.DrawingNo AS DrawingNumber,
                        m.Status,
                        m.MaterTypeId AS TypeId,
                        mt.TypeName,
                        m.CreateTime,
                        m.UpdatedTimes AS UpdateTime,
                        m.CreateUser AS CreateBy
                    FROM Mater m
                    LEFT JOIN MaterType mt ON m.MaterTypeId = mt.Id
                    WHERE {whereClause}
                    ORDER BY m.CreateTime DESC
                    LIMIT @Offset, @PageSize";

                parameters.Add("Offset", offset);
                parameters.Add("PageSize", request.PageSize);

                var materials = materRepository.Query<GetMaterialListDto>(dataSql, parameters)?.ToList() ?? new List<GetMaterialListDto>();

                // 构建分页结果
                var pagingResult = new APIPaging<GetMaterialListDto>
                {
                    PageDatas = materials,
                    TotalCount = totalCount
                };

                result.Code = APIEnums.Success;
                result.Data = pagingResult;
                result.Msg = "获取物料列表成功";

                logger.LogInformation("获取物料分页列表成功，共 {TotalCount} 条记录，当前页 {CurrentPage} 条记录",
                    totalCount, materials.Count);
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.Error;
                result.Msg = "获取物料列表失败";
                logger.LogError(ex, "获取物料分页列表失败: {Message}", ex.Message);
            }

            return await Task.FromResult(result);
        }

        /// <summary>
        /// 获取指定分类及其所有子分类的ID列表
        /// </summary>
        /// <param name="typeId">分类ID</param>
        /// <returns>分类ID列表</returns>
        private async Task<List<long>> GetAllChildTypeIds(long typeId)
        {
            var typeIds = new List<long> { typeId };
            var sql = "SELECT Id, ParentId FROM MaterType WHERE IsDeleted = false";
            var allTypes = materTypeRepository.Query<(long Id, long? ParentId)>(sql).ToList();

            // 递归获取所有子分类ID
            GetChildIds(allTypes, typeId, typeIds);

            return typeIds;
        }

        /// <summary>
        /// 递归获取子分类ID
        /// </summary>
        /// <param name="allTypes">所有分类数据</param>
        /// <param name="parentId">父级ID</param>
        /// <param name="result">结果列表</param>
        private void GetChildIds(List<(long Id, long? ParentId)> allTypes, long parentId, List<long> result)
        {
            var children = allTypes.Where(t => t.ParentId == parentId).ToList();
            foreach (var child in children)
            {
                result.Add(child.Id);
                GetChildIds(allTypes, child.Id, result);
            }
        }
    }
}